﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Threading;

namespace SplitMatch
{
    public partial class MainForm : Form
    {

        public List<String> ListBase; // 保存基准图的文件名字.
        public List<String> ListMatch; // 保存匹配图的文件名字.

        // 临时目录
        String MatchDir;

        // 保存Entrance地址
        Form entranceForm;

        // 截图控制变量
        Boolean bCutState = false;
        String mJIETU = "截图大小：";

        int mCurrentRow; // 截图辅助临时变量
        int mCurrentCol; // 截图辅助临时变量

        // 线程变量
        private Thread HandleThread;          // 发送数据的线程对象.
        Matching m_Match;                // 线程调用对象
        public bool bStartTread;            // 开始标志位.


        Image m_SetImage;   // 固定保存一张图片
        Image m_tempImage;  // 临时的需要不停被清除的变量

        public MainForm()
        {
            InitializeComponent();


            // 初始化.
            ListBase = new List<string>();
            ListMatch = new List<string>();

            
        }

        private void btnChooseBase_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = true;
            fileDialog.Title = "请选择文件";
            fileDialog.Filter = "所有文件(*.*)|*.*";

            int nCount = 0;

            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                string[] files = fileDialog.FileNames;

                // 用List把这次选择的文件记录下来
                nCount = files.Length;
                for (int i = 0; i < nCount; i++)
                {
                    // 这里需要做个判断，如果这个值已经存在，则不加入

                    bool bContains = this.listBoxBase.Items.Contains(files[i]);

                    if (false == bContains)
                    {
                        this.listBoxBase.Items.Add(files[i]);
                    }

                    

                    //this.ListBase.Add(files[i]);

                    // GetSingleFileName.
                    //String strSingle = myAssist.GetSingleFile(files[i]);

                    

                    //// 这里需要做个判断，如果这个值已经存在，则不加入
                    //bool bContains = this.listBoxBase.Items.Contains(strSingle);
                    //if (false == bContains)
                    //{
                    //    this.listBoxBase.Items.Add(strSingle);
                    //}                
                }
            }

            // 载入图片
            LoadPictures(listBoxBase, this.picBoxBase);

            
        }

        /// <summary>
        /// 从ListBoxBase提取图片给pictureBox加载
        /// </summary>
        /// <param name="listBoxBase"></param>
        /// <param name="pBox"></param>
        private void LoadPictures(ListBox lBox, PictureBox pBox)
        {
            // this.strFiles
            // 默认都是取第一个图片
            int nCount = lBox.Items.Count;
            if (nCount > 0)
            {
                // 加载第一个
                String strFile = lBox.Items[0].ToString();

                // 选中第一个图片
                lBox.SelectedItem = lBox.Items[0];

                mySize size = new mySize(0, 0);

                // 判断是不是tif结尾的.
                String[] parts = strFile.Split('.');
                String strHou = parts[1];

                if ((strHou == "tif") || (strHou == "TIF"))
                {
                    size = HandleTIF.GetSize(strFile);
                }
                else
                {
                    size = BasePicHandle.GetSize(strFile);

                }

                // 设定picturebox大小
                //mySize size = HandleTIF.GetSize(strFile);


                // 显示
                pBox.Width = size.COL;
                pBox.Height = size.ROW;


                // 通过流的方式 保存文件,不用把文件锁住.
                FileStream pFileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
                pBox.Image = Image.FromStream(pFileStream);
                //同时把文件值保存
                pBox.Tag = strFile;

                // 保存一副固定Image.
                m_SetImage = Image.FromFile(strFile);

                // 释放文件资源.
                pFileStream.Close();
                pFileStream.Dispose();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;

            // 设置256为选中状态
            rB256.Checked = true;

            // 设置自定义截图数字.
            tBMatch8.Text = "12";
            String strShow = GetShow(tBMatch8.Text);
            lSizeShow.Text = strShow;

            // 线程是否开始标志位.
            bStartTread = false;
        }

        /// <summary>
        /// 根据数字选择小图大小
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        private string GetShow(string p)
        {
            // strJieTu
            if ((null == p) || (String.Empty == p))
            {
                return String.Empty;
            }

            String strRtn = String.Empty;
            try
            {
                int nNum = Convert.ToInt32(p);

                nNum = nNum * 8;
                strRtn = mJIETU + nNum.ToString();
            }
            catch (Exception)
            {
                
                //throw;
                // 抛出异常时 不做处理. 给提示信息.
                MessageBox.Show("请输入数字");            
            }


            return strRtn;
        }

        private void btnChooseMatch_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = true;
            fileDialog.Title = "请选择文件";
            fileDialog.Filter = "所有文件(*.*)|*.*";
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {

                string[] files = fileDialog.FileNames;

                // 用List把这次选择的文件记录下来
                int nCount = files.Length;
                for (int i = 0; i < nCount; i++)
                {

                    bool bContains = this.listBoxMatch.Items.Contains(files[i]);

                    if (false == bContains)
                    {
                        this.listBoxMatch.Items.Add(files[i]);
                    }             
                }
            }

            // 载入图片
            // 输入List名字和空间名字
            LoadPictures(this.listBoxMatch, this.picBoxMatch);
        }


        private Int32 GetTime()
        {
            Int32 nRtn = 0;

            int nHour = System.DateTime.Now.Hour;
            int nMinute = System.DateTime.Now.Minute;
            int nSecond = System.DateTime.Now.Second;
            int nMilliSecond = System.DateTime.Now.Millisecond;

            nRtn = nMilliSecond + nSecond * 1000 + nMinute * 60 * 1000 + nHour * 3600 * 1000;


            return nRtn;
        }


        // 找到最佳位置并显示
        private void FindLocationShow(Location bestLocation, String strBase, String strMatch)
        {
            // 这里26*26就是图像可以匹配的位置, 当值最大时就是最佳匹配
            // FindLocation函数 找到最大值的位置并返回
            // 这个值代表匹配子图在基准图中的偏移量
            // 通过偏移量和匹配子图大小可以在基准图中找到最佳的匹配点


            // 这个MatrixG的意义是
            // 在这个矩阵里，有这么多个位置，返回了一个匹配度最好的值
            // 这个位置在这个矩阵里的偏移量，就认为是小图在大图里的偏移量

            String strSetName = String.Empty;

            String strFileName = strBase;
            // 如果是tif 用原有逻辑
            // 如果是其他图片，用新类型
            // 判断是不是tif结尾的.
            String[] parts = strFileName.Split('.');
            String strHou = parts[1];

            if ((strHou == "tif") || (strHou == "TIF"))
            {
                // 执行tif原型
                byte[,] Basepic = HandleTIF.ReadTifFile(strFileName);


                // 用偏移量和子图大小去改变基准图的元素，并显示基准图.
                // 获得picturebox 显示图片文件名字
                // 小图的Size也需要传进去.


                // 用bestLocation和MatrixG 算出偏移百分比
                // 用小图和大图算出 这个小图在这个大图里可以偏移的总量
                // 偏移总量 * 偏移百分比 = 需要标注的坐标点
                // 从这个点画一个小图大小的白框

                // Basepic : 大图矩阵
                // MatchPic: 小图矩阵
                // bestLocation: MatrixG中的最大值坐标点
                // MatrixG： 匹配矩阵


                // 拆分功能.
                // 1 返回一个匹配的坐标
                // 2 画图

                Location getLocation = bestLocation;

                // 导出结果.
                String strResult = string.Format("{0},{1}", getLocation.row, getLocation.column);
                tBResult.Text = strResult;

                // 在图片上画出白框
                byte[,] MatchPic = HandleTIF.ReadTifFile(strMatch);

                HandleTIF.DrawRetangle(Basepic, MatchPic, getLocation);


                strSetName = "Changed.tif";



                // 在对这个文件操作之前，要从picbox里把这个文件卸载了



                HandleTIF.SaveTIFFile(Basepic, strSetName);
            }
            else
            {
                //// 执行jpg原型，需要对RGB3个部分进行设置.

                //// 用一个新的image对象，把文件读取进来后，看看能不能保存成新的文件，或者直接替换

                //Image tempImage = Image.FromFile(strFileName);
                //mySize OriginSize = new mySize(0, 0);
                //OriginSize.COL = tempImage.Width;
                //OriginSize.ROW = tempImage.Height;

                //// 换算出精确坐标
                //Location getLocation = BasePicHandle.GetLocation(OriginSize,
                //                                                 MatchPic,
                //                                                bestLocation,
                //                                                MatrixG);

                //// 导出结果.
                //String strResult = string.Format("{0},{1}", getLocation.row, getLocation.column);
                //txtBResult.Text = strResult;

                //// 对图片 对tempImage进行改变 并保存
                //BasePicHandle.DrawRetangle(tempImage, MatchPic, getLocation);

                //strSetName = "Changed.tif";

                //// 保存图片 看看原图片有没有被改变
                //tempImage.Save(strSetName);

            }







            // Console.WriteLine();


            // 通过流的方式 保存文件,不用把文件锁住.
            FileStream pFileStream = new FileStream(strSetName, FileMode.Open, FileAccess.Read);
            this.picBoxBase.Image = Image.FromStream(pFileStream);

         
            // 释放文件资源.
            pFileStream.Close();
            pFileStream.Dispose();

        }

        // 找到矩阵中最大值的位置
        private Location FindLocation(Matrix MatrixG)
        {
            Location lRtn = new Location(0, 0);

            // 先找最大值
            double dMax = BasePicHandle.FindMax(MatrixG);


            // 再找位置
            lRtn = BasePicHandle.FindLocation(MatrixG, dMax);


            return lRtn;
        }

        private void btnCutPics_Click(object sender, EventArgs e)
        {
            //// 看看截图路径问题
            //// MatchDir

            //String strFolder = MatchDir;

            //// 设定越过像素值.
            //int nOffValue = 20;

            //int nSize = Convert.ToInt32(textBMatchSize.Text);

            //// 设定大小
            //int nRow = nSize;
            //int nCol = nSize;


            //// 选择张大图.
            //String strName = picBoxBase.Tag.ToString();

            //// 设定裁剪小图大小.
            //mySize cutSize = new mySize(nRow, nCol);

            //// 判断是不是TIF图
            //// 判断是不是tif结尾的.
            //mySize BaseSize = new mySize(0,0);
            //String[] parts = strName.Split('.');
            //String strHou = parts[1];

            //if ((strHou == "tif") || (strHou == "TIF"))
            //{
            //    BaseSize = HandleTIF.GetSize(strName);
            //}
            //else
            //{
            //    BaseSize = BasePicHandle.GetSize(strName);

            //}

            
            

            //// 默认目录.




            //if ((strHou == "tif") || (strHou == "TIF"))
            //{
            //    // 读取原图大小.
            //    // 计算截取图片i和j
            //    byte[,] bCsharp = HandleTIF.ReadTifFile(strName);

            //    // i j 为顶点位置

            //    for (int i = 0; i <= (BaseSize.ROW - cutSize.ROW); i = i + nOffValue)
            //    {
            //        for (int j = 0; j <= (BaseSize.COL - cutSize.COL); j = j + nOffValue)
            //        {
            //            // 获得顶点位置i和j
            //            Location point = new Location(i, j);

            //            byte[,] bSmall = HandleTIF.GetSmallM(point, bCsharp, cutSize);

            //            // 截取图像 保存名字

            //            // 保存后，提示保存成功
            //            // IR3_96_96_128_56.tif 唯一值.
            //            String strFile = GetFileName(strName,
            //                                         strFolder,
            //                                            cutSize.ROW,
            //                                            cutSize.COL,
            //                                            i,
            //                                            j
            //                                            );

            //            // 写文件
            //            HandleTIF.SaveTIFFile(bSmall, strFile);

            //        } // for j循环
            //    } // for i循环

            //}
            //else
            //{
            //    for (int i = 0; i <= (BaseSize.ROW - cutSize.ROW); i = i + nOffValue)
            //    {
            //        for (int j = 0; j <= (BaseSize.COL - cutSize.COL); j = j + nOffValue)
            //        {
            //            // 获得顶点位置i和j
            //            Location point = new Location(i, j);

            //            Bitmap smallBit = BasePicHandle.CutPic(strName, point, cutSize);

            //            // 在执行目录里 新建指定目录
            //            String strFile = GetFileNameDir(strName,
            //                    cutSize.ROW,
            //                    cutSize.COL,
            //                    i,
            //                    j
            //                    );

            //            smallBit.Save(strFile);

            //            // 释放内存.
            //            smallBit.Dispose();

            //        }
            //    }
            //}




            //// 提示信息.
            //MessageBox.Show("Cut Done");
        }

        /// <summary>
        /// 组合文件名字
        /// </summary>
        /// <param name="strName"></param>
        /// <param name="p"></param>
        /// <param name="p_2"></param>
        /// <param name="i"></param>
        /// <param name="j"></param>
        /// <returns></returns>
        private string GetFileNameDir(string strName, int p, int p_2, int i, int j)
        {
            
            string[] strs = strName.Split('.');
            String str = strs[0] + "_" + p.ToString() + "_" + p_2.ToString() + "_" +
                i.ToString() + "_" + j.ToString() + "." + strs[1];

            return str;
        }

        // 拼接文件名字
        private String GetFileName(string p, string strFolder, int p_2, int p_3, int p_4, int p_5)
        {
            String strRtn = String.Empty;
            // IR3_96_96_128_56.tif 唯一值.
            string[] strs = p.Split('.');

            // 取得文件名字
            String strFileFullName = strs[0];

            String[] strtemps = strFileFullName.Split('\\');

            String strFileSingleName = strtemps[strtemps.Length - 1];

            String str = strFolder + "\\" + strFileSingleName + "_" + p_2.ToString() + "_" + p_3.ToString() + "_" +
                            p_4.ToString() + "_" + p_5.ToString() + "." + strs[1];

            return str;
        }

        // 换个目录存放文件
        private string ReplaceDir(string str)
        {
            String strRtn = String.Empty;

            string[] temps = str.Split('\\');
            temps[temps.Length - 2] = this.MatchDir;

            for (int i = 0; i < temps.Length; i++)
            {
                if (0 == i)
                {
                    strRtn = temps[i];
                }
                else
                {
                    strRtn = strRtn + "\\" + temps[i];
                }

            }
            return strRtn;
        }

        private void btnSingleMatch_Click(object sender, EventArgs e)
        {

            // 清除结果.
            tBResult.Text = String.Empty;
            tBTime.Text = String.Empty;

            String strBase = picBoxBase.Tag.ToString();
            String strMatch = picBoxMatch.Tag.ToString();

            // 所有写界面的信息都放在一个信息框里,
            // 感觉耦合度很大.
            m_Match = new Matching(
                                    this.tBOriL,
                                    tBResult,
                                    tBTime,
                                    picBoxBase,
                                    btnSingleMatch,
                                    strBase,
                                    strMatch);

            HandleThread = new Thread(new ThreadStart(m_Match.ThreadMatch));
            HandleThread.Priority = ThreadPriority.Highest;
            HandleThread.Start();

            Console.WriteLine();
        }


        private void btnAllMatch_Click(object sender, EventArgs e)
        {
            //String strLog = "Log.txt";
            //String strDir = MatchDir;


            //// label 结果标签
            //// log 位置.
            //// 目录位置.
            //// 按钮设置属性.

            //// AllMResult 显示处理图片的进程和文件名字
            //// 传递MatchBase 用于显示正在处理的图片
            //// 传递Origin 用于显示位置



            //m_Match = new Matching(
            //                        AllMResult,
            //                        strLog,
            //                        strDir,
            //                        picBoxBase,
            //                        picBoxMatch,
            //                        tBOriL,
            //                        btnAllMatch);

            //HandleThread = new Thread(new ThreadStart(m_Match.ThreadAllMatch));
            //HandleThread.Priority = ThreadPriority.Highest;
            //HandleThread.Start();

            //// 设置一个标志位.
            //bStartTread = true;

            //Console.WriteLine();
     
        }

        /// <summary>
        /// 查询fileLocation是否存在于logFiles里
        /// </summary>
        /// <param name="fileLocation"></param>
        /// <param name="logFiles"></param>
        /// <returns>TRUE:处理过 FLASE：没有处理</returns>
        private bool CheckIfHandled(string fileLocation, List<string> logFiles)
        {
            bool bRtn = false;

            bool bContains = logFiles.Contains(fileLocation);

            // 如果存在文件，则认为处理过.
            bRtn = bContains;

            return bRtn;
        }

        /// <summary>
        /// 从完整的文件名提取坐标形式的名字
        /// </summary>
        /// <param name="strEach"></param>
        /// <returns></returns>
        private string GetLocationForm(string strEach)
        {

            String[] parts = strEach.Split('\\');


            // 用_获取 row 和 col
            String fileName = parts[parts.Length - 1];
            String[] withOutparts = fileName.Split('.');
            fileName = withOutparts[0];

            String[] Smallparts = fileName.Split('_');


            String fileLocation = String.Format("{0},{1}",
                                                Smallparts[3],
                                                Smallparts[4]);
            return fileLocation;
        }

        /// <summary>
        /// 从Log文件获取已经完成的匹配结果
        /// </summary>
        /// <param name="strLog"></param>
        /// <returns></returns>
        private List<string> GetRecord(string strLog)
        {
            List<string> strList = new List<string>();

            StreamReader sr = new StreamReader(strLog);

            String line;
            // Read and display lines from the file until the end of 
            // the file is reached.
            while ((line = sr.ReadLine()) != null)
            {
                // 切断line 提取需要的资源.
                String[] parts = line.Split(' ');
                strList.Add(parts[0]);
            }

            sr.Close();
            sr.Dispose();


            return strList;
        }

        /// <summary>
        /// 写一条记录
        /// </summary>
        /// <param name="strLog"></param>
        /// <param name="fileName"></param>
        private void WriteLog(string strLog, string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Append);
            StreamWriter sw = new StreamWriter(fs);
            //开始写入
            sw.WriteLine(strLog);


            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();
        }

        /// <summary>
        /// 获得匹配位置
        /// </summary>
        /// <param name="strEach"></param>
        /// <param name="strBaseName"></param>
        /// <returns></returns>
        private SplitMatch.Location GetMatchLocation(string strEach, string strBaseName)
        {
            Location rtnL = new Location(0, 0);

            // 读取图片
            double[,] PicBase = BasePicHandle.GetPicData(strBaseName);
            double[,] PicSmall = BasePicHandle.GetPicData(strEach);


            // 分割矩阵
            mySize baseSmallSize = new mySize(8, 8);
            Matrix[,] MyBaseM = BasePicHandle.SplitMatrix(PicBase, baseSmallSize);
            Matrix[,] MyMatrixS = BasePicHandle.SplitMatrix(PicSmall, baseSmallSize);

            // 12个偏移量 为了求得新矩阵
            // 可以作为一个常量 放到另一个CS文件里
            Location[] Lvector = new Location[12];

            Lvector[0].row = -2;
            Lvector[0].column = -2;

            Lvector[1].row = -2;
            Lvector[1].column = -1;

            Lvector[2].row = -2;
            Lvector[2].column = 0;

            Lvector[3].row = -2;
            Lvector[3].column = 1;

            Lvector[4].row = -2;
            Lvector[4].column = 2;

            Lvector[5].row = -1;
            Lvector[5].column = -2;

            Lvector[6].row = -1;
            Lvector[6].column = -1;

            Lvector[7].row = -1;
            Lvector[7].column = 0;

            Lvector[8].row = -1;
            Lvector[8].column = 1;

            Lvector[9].row = -1;
            Lvector[9].column = 2;

            Lvector[10].row = 0;
            Lvector[10].column = -2;

            Lvector[11].row = 0;
            Lvector[11].column = -1;

            // 输入一个嵌套矩阵，输出一个List Matrix集合
            List<Matrix> MBiglist = BasePicHandle.GetMatrixList(MyBaseM, Lvector);
            List<Matrix> MSmalist = BasePicHandle.GetMatrixList(MyMatrixS, Lvector);

            // 输入2个Matrix List， 输出整合好12通道数据的
            // 匹配矩阵
            Matrix MatrixG = BasePicHandle.PiPeiMatrix(MBiglist, MSmalist, Lvector);


            // 找到匹配位置并返回.


            // 这里26*26就是图像可以匹配的位置, 当值最大时就是最佳匹配
            // FindLocation函数 找到最大值的位置并返回
            // 这个值代表匹配子图在基准图中的偏移量
            // 通过偏移量和匹配子图大小可以在基准图中找到最佳的匹配点


            // 这个MatrixG的意义是
            // 在这个矩阵里，有这么多个位置，返回了一个匹配度最好的值
            // 这个位置在这个矩阵里的偏移量，就认为是小图在大图里的偏移量

            Location bestLocation = FindLocation(MatrixG);


            String strFileName = (String)picBoxBase.Tag;



            // 不同的类型 做不同的处理
            String[] parts = strFileName.Split('.');
            String strHou = parts[1];

            if ((strHou == "tif") || (strHou == "TIF"))
            {
                // TIF

                byte[,] Basepic = HandleTIF.ReadTifFile(strFileName);


                // 用偏移量和子图大小去改变基准图的元素，并显示基准图.
                // 获得picturebox 显示图片文件名字
                // 小图的Size也需要传进去.


                // 用bestLocation和MatrixG 算出偏移百分比
                // 用小图和大图算出 这个小图在这个大图里可以偏移的总量
                // 偏移总量 * 偏移百分比 = 需要标注的坐标点
                // 从这个点画一个小图大小的白框

                // Basepic : 大图矩阵
                // MatchPic: 小图矩阵
                // bestLocation: MatrixG中的最大值坐标点
                // MatrixG： 匹配矩阵

                // 用bestLocation和MatrixG 算出偏移百分比
                // 用小图和大图算出 这个小图在这个大图里可以偏移的总量
                // 偏移总量 * 偏移百分比 = 需要标注的坐标点
                // 从这个点画一个小图大小的白框

                // Basepic : 大图矩阵
                // MatchPic: 小图矩阵
                // bestLocation: MatrixG中的最大值坐标点
                // MatrixG： 匹配矩阵


                // (0,0)点代表有8格的误差,
                // 从(4,4)点开始，作为内圈向外扩展
                // 算出偏移百分比 比如在26 26 中的位置 就是一个值
                // 这个值 / 26 获得偏移百分比值
                // 然后在200*200 与 400*400 的关系里， 带入这个偏移百分比值, 获得偏移像素值
                // 由左上角点 + 偏移像素值  就可以做出图形
                // 如果返回起始位置，则认为偏移量是1%



                double dOffRow;
                double dOffCol;
                // 偏移百分比，如果是0， 则返回0.01.
                if (0 == bestLocation.row)
                {
                    dOffRow = 0.01;
                }
                else
                {
                    dOffRow = Convert.ToDouble(bestLocation.row) / MatrixG.Row;
                }

                if (0 == bestLocation.column)
                {
                    dOffCol = 0.01;
                }
                else
                {
                    dOffCol = Convert.ToDouble(bestLocation.column) / MatrixG.Column;
                }


                // 算出偏移总量
                int nOffRowSum = BasePicHandle.GetROW(Basepic) - BasePicHandle.GetROW(PicSmall);
                int nOffColSum = BasePicHandle.GetCOL(Basepic) - BasePicHandle.GetCOL(PicSmall);


                // 算出需要标注的坐标点  =  偏移总量 * 偏移百分比

                int nLRow = Convert.ToInt32(Math.Floor(dOffRow * nOffRowSum));
                int nLCol = Convert.ToInt32(Math.Floor(dOffCol * nOffColSum));

                rtnL.row = nLRow;
                rtnL.column = nLCol;
            }
            else
            {
                // others

                Image tempImage = Image.FromFile(strFileName);
                mySize OriginSize = new mySize(0, 0);
                OriginSize.COL = tempImage.Width;
                OriginSize.ROW = tempImage.Height;



                // 换算出精确坐标
                Location getLocation = BasePicHandle.GetLocation(OriginSize,
                                                                 PicSmall,
                                                                bestLocation,
                                                                MatrixG);

                rtnL.row = getLocation.row;
                rtnL.column = getLocation.column;
            }
            

            // 释放资源.
            

            return rtnL;
        }

        /// <summary>
        /// 对匹配结果进行分析，
        /// 得到2个新的txt文档和一个匹配成功的比率
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAnalyse_Click(object sender, EventArgs e)
        {
            //// Log
            //String strLog = "Log.txt";

            //int nOff = 15;

            //// 读取Log记录
            //List<String> logFiles = GetFullRecord(strLog);

            ////
            //List<String> susFiles = new List<string>();
            //List<String> falFiles = new List<string>();

            //int nNum = logFiles.Count;
            //for (int i = 0; i < nNum; i++)
            //{
            //    // 对每条记录进行处理
            //    String strEach = logFiles[i];

            //    bool bSus = false;


            //    bSus = CheckIfSus(strEach, nOff);
            //    // 成功时 放一个容器里
            //    if (true == bSus)
            //    {
            //        susFiles.Add(strEach);
            //    }
            //    else
            //    {
            //        // 不成功时 放另一个容器里
            //        falFiles.Add(strEach);
            //    }          
            //}





            //// 比值对比
            //Decimal deSus = Convert.ToDecimal(susFiles.Count);
            //Decimal deAll = Convert.ToDecimal(logFiles.Count);
            //Decimal ChengGongBi = deSus / deAll;

            //ChengGongBi = Math.Round(ChengGongBi, 4);

            //// *100
            //ChengGongBi = ChengGongBi * 100;
            //ChengGongBi = Math.Round(ChengGongBi, 2);

            //String strNum = ChengGongBi.ToString();
            //String strShow = String.Format("{0}%", strNum);
            //ShowPiPei.Text = strShow;


            //// 用容器写出文件
            //WriteLog(susFiles, "susLog.txt");
            //WriteLog(falFiles, "falLog.txt");
            //WriteLog(strShow, "pipei.txt");

        }

        /// <summary>
        /// 写多个字段到文件里
        /// </summary>
        /// <param name="susFiles"></param>
        /// <param name="p"></param>
        private void WriteLog(List<string> susFiles, string fileName)
        {
            FileStream fs = new FileStream(fileName, FileMode.Append);
            StreamWriter sw = new StreamWriter(fs);

            int nNum = susFiles.Count;
            for (int i = 0; i < nNum; i++)
            {
                //开始写入
                String strEach = susFiles[i];
                sw.WriteLine(strEach);
            }

            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();
        }


        /// <summary>
        /// 读取文件 得到String结果
        /// </summary>
        /// <param name="strLog"></param>
        /// <returns></returns>
        private List<string> GetFullRecord(string strLog)
        {
            List<string> strList = new List<string>();

            StreamReader sr = new StreamReader(strLog);

            String line;
            // Read and display lines from the file until the end of 
            // the file is reached.
            while ((line = sr.ReadLine()) != null)
            {
                strList.Add(line);
            }

            sr.Close();
            sr.Dispose();

            return strList;
        }

        /// <summary>
        /// 通过误差分析 是否匹配成功
        /// </summary>
        /// <param name="strEach"></param>
        /// <returns></returns>
        private bool CheckIfSus(string strEach, int OffValue)
        {
            bool bRtn = false;


            // 拆分
            String[] parts = strEach.Split(' ');

            // 原图坐标
            String[] OriParts = parts[0].Split(',');
            int oriRow = Convert.ToInt32(OriParts[0]);
            int oriCol = Convert.ToInt32(OriParts[1]);

            // 匹配坐标
            String[] MatchParts = parts[1].Split(',');
            int matRow = Convert.ToInt32(MatchParts[0]);
            int matCol = Convert.ToInt32(MatchParts[1]);

            // 两个结果都必须满足
            bool OriOK = false;
            bool MatOK = false;

            int offOri = Math.Abs(oriRow - matRow);
            int offMat = Math.Abs(oriCol - matCol);

            if (offOri <= OffValue)
            {
                OriOK = true;
            }

            if (offMat <= OffValue)
            {
                MatOK = true;
            }


            bRtn = OriOK && MatOK;

            return bRtn;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Matching myMatch = new Matching();

            //Location l = myMatch.Match("ccd.tif", "ir_256_256_0_500.tif");

        }

        private void btnChooseDir_Click(object sender, EventArgs e)
        {

            //FolderBrowserDialog folderDlg = new FolderBrowserDialog();
            //folderDlg.ShowDialog();
            ////MessageBox.Show(folderDlg.SelectedPath);

            //MatchDir = folderDlg.SelectedPath;

            //lDir.Text = MatchDir;

        }

        /// <summary>
        /// 清除图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClearBase_Click(object sender, EventArgs e)
        {
            ClearPictures(listBoxBase, this.picBoxBase);
        }

        /// <summary>
        /// 函数方式 处理
        /// </summary>
        /// <param name="listBoxBase"></param>
        /// <param name="pictureBox"></param>
        private void ClearPictures(ListBox lBox, PictureBox pictureBox)
        {
            // 处理listBox
            lBox.Items.Clear();


            // pictureBox设置为空
            pictureBox.Image = null;
        }

        private void btnClearMatch_Click(object sender, EventArgs e)
        {
            ClearPictures(listBoxMatch, this.picBoxMatch);
        }

        private void listBoxBase_SelectedIndexChanged(object sender, EventArgs e)
        {


            ChangePictures(listBoxBase, this.picBoxBase);

            // 需要设置m_SetImage 来针对当前选中的Base图片.
            String strFile = this.picBoxBase.Tag.ToString();
            m_SetImage = Image.FromFile(strFile);

        }


        private void ChangePictures(ListBox lBox, PictureBox pBox)
        {
            // 获得当前选项.


            // 加载第一个
            String strFile = lBox.SelectedItem.ToString();

            mySize size = new mySize(0, 0);

            // 判断是不是tif结尾的.
            String[] parts = strFile.Split('.');
            String strHou = parts[1];

            if ((strHou == "tif") || (strHou == "TIF"))
            {
                size = HandleTIF.GetSize(strFile);
            }
            else
            {
                size = BasePicHandle.GetSize(strFile);

            }

            // 设定picturebox大小
            //mySize size = HandleTIF.GetSize(strFile);


            // 显示
            pBox.Width = size.COL;
            pBox.Height = size.ROW;


            // 通过流的方式 保存文件,不用把文件锁住.
            FileStream pFileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
            pBox.Image = Image.FromStream(pFileStream);
            //同时把文件值保存
            pBox.Tag = strFile;

            // 释放文件资源.
            pFileStream.Close();
            pFileStream.Dispose();

        }

        private void listBoxMatch_SelectedIndexChanged(object sender, EventArgs e)
        {
            ChangePictures(listBoxMatch, this.picBoxMatch);
        }

        /// <summary>
        /// 保留Entrance的地址 用来关闭使用
        /// </summary>
        /// <param name="entrance"></param>
        public void getStartL(Entrance entrance)
        {
            entranceForm = entrance;
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (null != entranceForm)
            {
                entranceForm.Close();
            }

            if (true == bStartTread)
            {
                // 通过函数设置标志位
                // 不明确后面的Join是否要需要？

                m_Match.RequestStop();
                HandleThread.Join();
            }
            
        }

        private void btnCut_Click(object sender, EventArgs e)
        {
            if (false == bCutState)
            {
                // 打开截图
                bCutState = true;
                btnCut.Text = "取消截图";
            }
            else
            {
                // 关闭截图

                bCutState = false;
                btnCut.Text = "截图";

                // 重新加载图片
                ReLoadBase();
            }
        }

        /// <summary>
        /// 截图后 重新加载以前的图片
        /// </summary>
        private void ReLoadBase()
        {
            
            // 加载第一个
            String strFile = listBoxBase.SelectedItem.ToString();

            // 选中第一个图片
            // lBox.SelectedItem = lBox.Items[0];

            mySize size = new mySize(0, 0);

            // 判断是不是tif结尾的.
            String[] parts = strFile.Split('.');
            String strHou = parts[1];

            if ((strHou == "tif") || (strHou == "TIF"))
            {
                size = HandleTIF.GetSize(strFile);
            }
            else
            {
                size = BasePicHandle.GetSize(strFile);

            }

            // 设定picturebox大小
            //mySize size = HandleTIF.GetSize(strFile);

            
            // 显示
            picBoxBase.Width = size.COL;
            picBoxBase.Height = size.ROW;


            // 通过流的方式 保存文件,不用把文件锁住.
            FileStream pFileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
            picBoxBase.Image = Image.FromStream(pFileStream);
            //同时把文件值保存
            picBoxBase.Tag = strFile;

            // 释放文件资源.
            pFileStream.Close();
            pFileStream.Dispose();
        }

        private void picBoxBase_MouseMove(object sender, MouseEventArgs e)
        {
            // 只有截图状态有效时，才截图
            if (true == bCutState)
            {

                // 保存当前鼠标坐标.
                this.mCurrentRow = e.Y;
                this.mCurrentCol = e.X;

                // 大问题，每次都会去加载文件. ！！！！！！！！！！！！！！！！！！！！！
                // 要做一个变量能够初始化 Image 并且是放在内存里的!!!!!!!!!!!!!!!!!!!!

                // 只用一个局部变量，在移动时把之前的变量释放掉
                if (null != m_tempImage)
                {
                    m_tempImage.Dispose();
                }

                //String strCurBase = picBoxBase.Tag.ToString();
                //Image image1 = Image.FromFile(strCurBase);

                // 设定Image为一个固定源         
                //Bitmap bmp = new Bitmap(image1);

                //Bitmap bmp = new Bitmap(m_SetImage);

                m_tempImage = new Bitmap(m_SetImage);

                // Bitmap bmp = new Bitmap("ir.tif");
                Graphics g = Graphics.FromImage(m_tempImage);

                // 判断哪个规格被选中，就写多大.
                mySize size = GetSizeFromControls();

                g.DrawRectangle(new Pen(Color.White), e.X, e.Y, size.ROW, size.COL);
                g.Dispose();

                // 把内存里的值 重新赋值到picMain.Image里
                this.picBoxBase.Image = m_tempImage;


            }
        }

        /// <summary>
        /// 根据选择设置小图大小
        /// </summary>
        /// <returns></returns>
        private mySize GetSizeFromControls()
        {
            mySize sizeRtn = null;

            if (true == rB96.Checked)
            {
                sizeRtn = new mySize(96, 96);
            }

            if (true == rB128.Checked)
            {
                sizeRtn = new mySize(128, 128);
            }

            if (true == rB256.Checked)
            {
                sizeRtn = new mySize(256, 256);
            }

            if (true == rBCustom.Checked)
            {
                int nSize = Convert.ToInt32(tBMatch8.Text);
                sizeRtn = new mySize(nSize * 8, nSize * 8);
            }

            return sizeRtn;
        }

        private void tBMatch8_TextChanged(object sender, EventArgs e)
        {
            String strShow = GetShow(tBMatch8.Text);

            lSizeShow.Text = strShow;
        }

        private void picBoxBase_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //MessageBox.Show(strTest);
            Location point = new Location(this.mCurrentRow, this.mCurrentCol);

            // 读取一幅同名文件.
            String strCurBase = picBoxBase.Tag.ToString();
            byte[,] bCsharp = HandleTIF.ReadTifFile(strCurBase);


            // 根据坐标， 尺寸大小截取图形.
            mySize size = GetSizeFromControls();
            byte[,] bSmall = HandleTIF.GetSmallM(point, bCsharp, size);

            // 保存后，提示保存成功
            // IR3_96_96_128_56.tif 唯一值.
            String strFile = GetLocalFileName(strCurBase,
                                            size.ROW,
                                            size.COL,
                                            this.mCurrentRow,
                                            this.mCurrentCol
                                            );



            // 写文件
            HandleTIF.SaveTIFFile(bSmall, strFile);

            // 保存到List里 回匹配窗口可以用
            MessageBox.Show(strFile);

            // 加入listbox里. 并且标记为选中.
            listBoxMatch.Items.Add(strFile);
            listBoxMatch.SelectedItem = strFile;

            // 自动加载这一张图片
            LoadPicture(strFile, picBoxMatch);

            
            // 更新
            //this.strCurSub = strFile;

            //strMatchFiles.Add(strFile);

            // Show Matches Pictures.
            //ShowMatchesPics();

            // 显示文件名字.
            //String strSingleFile = myAssist.GetSingleFile(strFile);
            //SubText.Text = strSingleFile;

            // GetSingleFileName.
            //this.listBoxSub.Items.Add(strSingleFile);
        }

        private void LoadPicture(string strFile, PictureBox pBox)
        {
            //// 加载第一个
            //String strFile = lBox.Items[0].ToString();

            //// 选中第一个图片
            //lBox.SelectedItem = lBox.Items[0];

            mySize size = new mySize(0, 0);

            // 判断是不是tif结尾的.
            String[] parts = strFile.Split('.');
            String strHou = parts[1];

            if ((strHou == "tif") || (strHou == "TIF"))
            {
                size = HandleTIF.GetSize(strFile);
            }
            else
            {
                size = BasePicHandle.GetSize(strFile);

            }

            // 设定picturebox大小
            //mySize size = HandleTIF.GetSize(strFile);


            // 显示
            pBox.Width = size.COL;
            pBox.Height = size.ROW;


            // 通过流的方式 保存文件,不用把文件锁住.
            FileStream pFileStream = new FileStream(strFile, FileMode.Open, FileAccess.Read);
            pBox.Image = Image.FromStream(pFileStream);
            //同时把文件值保存
            pBox.Tag = strFile;

            // 释放文件资源.
            pFileStream.Close();
            pFileStream.Dispose();
        }

        /// <summary>
        /// 截图程序保存在本地
        /// </summary>
        /// <param name="strCurBase"></param>
        /// <param name="p"></param>
        /// <param name="p_2"></param>
        /// <param name="p_3"></param>
        /// <param name="p_4"></param>
        /// <returns></returns>
        private string GetLocalFileName(string strCurBase, int p, int p_2, int p_3, int p_4)
        {
            String strRtn = String.Empty;
            // IR3_96_96_128_56.tif 唯一值.
            string[] strs = strCurBase.Split('.');

            // 取得文件名字
            String strFileFullName = strs[0];

            String[] strtemps = strFileFullName.Split('\\');

            String strFileSingleName = strtemps[strtemps.Length - 1];

            String str = strFileSingleName + "_" + p.ToString() + "_" + p_2.ToString() + "_" + p_3.ToString() + "_" +
                            p_4.ToString()+ "." + strs[1];

            return str;
        }
    }
}
